package com.eric.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eric.domain.dto.MaterialDto;
import com.eric.domain.dto.MaterialInDto;
import com.eric.domain.dto.MaterialOutDto;
import com.eric.domain.dto.MaterialPhotoDto;
import com.eric.domain.po.Material;
import com.eric.domain.po.MaterialIn;
import com.eric.domain.po.MaterialOut;
import com.eric.domain.po.MaterialPhoto;
import com.eric.mapper.MaterialInMapper;
import com.eric.mapper.MaterialMapper;
import com.eric.mapper.MaterialOutMapper;
import com.eric.service.ILocationService;
import com.eric.service.IMaterialPhotoService;
import com.eric.service.IMaterialService;
import com.eric.service.ISysUserService;
import com.eric.utils.FilesDownLoad;
import com.eric.utils.PublicTools;
import com.eric.utils.ServerBASEURL;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.DeleteJoinWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.eric.utils.Constant.PAGE_CURRENT;
import static com.eric.utils.Constant.PAGE_SIZE;

/**
 * <p>
 * 材料表 服务实现类
 * </p>
 *
 * @author 新哥
 * @since 2024-03-12
 */
@Service
@Transactional
@RequiredArgsConstructor
public class MaterialServiceImpl extends MPJBaseServiceImpl<MaterialMapper, Material> implements IMaterialService {
    //    配置encode的前缀
    private final static String ENCODE_PREFIX="MATERIAL";
    private final MaterialInMapper materialInMapper;
    private final MaterialOutMapper materialOutMapper;
    //   判断当前用户权限的布尔值,用于通过登录用户的权限，选择性地决定是否通过location查询数据
//    PublicTools.checkLoginRole();

    //    用于创建服务器磁盘的文件夹-日期
    SimpleDateFormat sdf=new SimpleDateFormat("/yyyy/MM/dd/");
    //    用于做图片文件的文件名-时间
    SimpleDateFormat tdf=new  SimpleDateFormat("yyyyMMdd");
    //    用于Location中的locationName
//    private final LocationMapper locationMapper;
    @Value("${file.location}")
    String fileLocation;
    //    用于做创建服务器磁盘的文件夹
    String materialPhotoPath="/materialPhotos";
    //    调用materialPhotoService，用于存储图片
    private final IMaterialPhotoService materialPhotoService;
    //    通过userService获取到真实姓名用于create_by和last_update_by
    private final ISysUserService userService;

    private final ILocationService locationService;




    @Override
    @Transactional
    public SaResult saveMaterialService(MaterialDto materialDto, MultipartFile[] materialFiles, HttpServletRequest request) {

        if (materialDto == null) {
            return SaResult.error("对象不能为空");
        }
//        去掉多余的空字符串，encode不用，因为这个是自动生成的
        MaterialDto checkedMaterialDto = checkMaterial(materialDto);
//       materialFiles:可选项；materialName:必选项;brand：必选项；pieces:必选项；number:必选项
//        model:必选项；
        if (checkedMaterialDto.getNumber()<=0){
            return SaResult.error("number不符合要求。");
        }
        if (StrUtil.isBlank(checkedMaterialDto.getMaterialName())){
            return SaResult.error("materialName不能为空");
        }
        if (StrUtil.isBlank(checkedMaterialDto.getBrand())){
            return SaResult.error("brand不能为空");
        }
        if (StrUtil.isBlank(checkedMaterialDto.getPieces())){
            return SaResult.error("pieces不能为空");
        }
        if (StrUtil.isBlank(checkedMaterialDto.getModel())){
            return SaResult.error("model不能为空");
        }

//       todo 通过material_name查询数据库中是否有同样名字的数据行 这里在这个materialIn里面的新物料进场已经做了判断，所以不需要做
//        Material materialInDb = query()
//                .eq("material_name", materialDto.getMaterialName())
//                .eq("brand",materialDto.getBrand())
//                .eq("model",materialDto.getModel())
//                .eq("location",materialDto.getLocation())
//                .one();
////        如果materialInDb不为空，就说明物料名称已存在，不能存储
//        if (!BeanUtil.isEmpty(materialInDb)){
//            return SaResult.error("物料名称已存在");
//        }
//        自动生成encode
        String encode_suffix = RandomUtil.randomString(5).toUpperCase();
        String dateFormat = tdf.format(new Date());
        String material_encode = ENCODE_PREFIX + dateFormat + encode_suffix;
        checkedMaterialDto.setEncode(material_encode);

//        获取到当前登录用户的userId
        Object loginId = StpUtil.getLoginId();
        int userId = Integer.parseInt(loginId.toString());
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }
//        把location字符串放在equipmentDto中
        checkedMaterialDto.setLocation(locationAddress);
//        如果meterialFile[]不为空
        if (materialFiles!=null){
            fileOperation(material_encode,materialFiles,request);

        }
        Material material = BeanUtil.copyProperties(checkedMaterialDto, Material.class);
//        通过登录Id和userService，获取到用户的realName
        String realname = userService.getById(userId).getRealName();
        material.setCreateBy(realname);
        save(material);
        return SaResult.data(BeanUtil.copyProperties(material, MaterialDto.class));
    }

    @Override
    @Transactional
    public SaResult modifyOne(MaterialDto materialDto, MultipartFile[] materialFile, HttpServletRequest request, String[] photoList) {
        if (materialDto == null) {
            return SaResult.error("不能为空");
        }
//        检查字段，把空字符串设定为Null
        MaterialDto checkMaterial = checkMaterial(materialDto);
//        对前端传输的对象字段，判定是否满足要求
//        id：必选；materialFile：可选项；photoList：可选项；materialName:可选项
//        number:可选项；pieces:可选项；description:可选项
        if (checkMaterial.getId()==null||checkMaterial.getId()<=0){
            return SaResult.error("id值不符合要求");
        }
        Material materialInDb = query().eq("id", checkMaterial.getId()).one();
        if(BeanUtil.isEmpty(materialInDb)){
            return SaResult.error("没有此项材料，请核实");
        }
//     todo   这个判断的意义何在？？  通过id查询material,当中只是查询encode字段值
       /* Material material = query().eq("id", checkMaterial.getId()).select("encode").one();
        if (!material.getEncode().equals(checkMaterial.getEncode())){
            return SaResult.error("encode和数据库中的encode不匹配");
        }*/
//       删除前端传进来的文件名的文件

//          todo  下面是直接删除服务器中对应的文件，是否有必要？这个根据具体策略加上，目前策略是不删除文件，弊端是文件越来越多，占用服务器空间
           /* for (String photoUrl : photoList) {
                String substring = photoUrl.substring(photoUrl.indexOf("e") + 2);
                FileUtil.del(fileLocation+substring);
            }*/

//       调用MaterialPhotoService逻辑删除material_photo表中对一个前端传进来的文件名的文件的数据
        if ( photoList!=null&&photoList.length>0){
            materialPhotoService.deleteByPhotoUrlList(Arrays.asList(photoList));
        }


        MaterialDto materialDtoByQuery = BeanUtil.copyProperties(materialInDb, MaterialDto.class);
//        todo 前端如果没有传进来的materialFile，应该判断null，而不是length<0，切记
        if (materialFile!=null){
            fileOperation(materialDtoByQuery.getEncode(),materialFile,request);
        }
        Object loginId = StpUtil.getLoginId();
        int i = Integer.parseInt(loginId.toString());
        String realName = userService.getById(i).getRealName();
        Material material = BeanUtil.copyProperties(checkMaterial, Material.class);

        material.setLastUpdateBy(realName);

        if (StrUtil.isBlank(material.getLayout())){
            material.setLayout(null);
        }

        boolean booleanMaterial = updateById(material);

        if (booleanMaterial){
//         todo   这里需要在数据库查询Material,而不是用上面前端传来得material，否则有些信息会缺失？？？ 再想想这个逻辑
            Material materialById = getById(material.getId());
            MaterialInDto materialInDTO = BeanUtil.copyProperties(materialById, MaterialInDto.class);
            MaterialOutDto materialOutDTO = BeanUtil.copyProperties(materialById, MaterialOutDto.class);
//      重新设置materialInDTO
            materialInDTO.setMaterialId(materialById.getId());
            materialInDTO.setId(null);
            materialInDTO.setWarehouse(materialById.getLocation());
            materialInDTO.setNumber(0);
            materialInDTO.setUpdateTime(null);
            materialInDTO.setCreateTime(null);
            materialInDTO.setEncode(null);
            materialInDTO.setDescription(null);
            materialInDTO.setCreateBy(null);
            materialInDTO.setCreateTime(null);
            materialInDTO.setUpdateTime(null);
            materialInDTO.setMaterialInPhotoList(null);
//      重新设置materialOutDTO
            materialOutDTO.setMaterialId(materialById.getId());
            materialOutDTO.setId(null);
            materialOutDTO.setWarehouse(materialById.getLocation());
            materialOutDTO.setNumber(0);
            materialOutDTO.setCreateTime(null);
            materialOutDTO.setUpdateTime(null);
            materialOutDTO.setEncode(null);
            materialOutDTO.setDescription(null);
            materialOutDTO.setCreateBy(null);
            materialOutDTO.setCreateTime(null);
            materialOutDTO.setUpdateTime(null);
            materialOutDTO.setMaterialOutPhotoList(null);
//          根据获取到得materialInDTO和materialOutDTO,修改相关materialIn和materialOut的表单

            UpdateWrapper<MaterialIn> materialInWrapper=new UpdateWrapper<>();
            materialInWrapper.eq("material_id",materialInDTO.getMaterialId());
            MaterialIn materialIn = BeanUtil.copyProperties(materialInDTO, MaterialIn.class);

            UpdateWrapper<MaterialOut> materialOutWrapper=new UpdateWrapper<>();
            materialOutWrapper.eq("material_id",materialOutDTO.getMaterialId());
            MaterialOut materialOut= BeanUtil.copyProperties(materialOutDTO, MaterialOut.class);

//            materialIn和materialOut同步修改
            materialInMapper.update(materialIn, materialInWrapper);
            materialOutMapper.update(materialOut, materialOutWrapper);
        }
        return   SaResult.ok("succeed！");
    }

    @Override
    public SaResult getAllByPageService(Integer current, Integer pageSize) {
        if (current==null||current<=0){
            current = PAGE_CURRENT;
        }
        if (pageSize==null||pageSize<=0){
            pageSize = PAGE_SIZE;
        }
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }

        Page<MaterialDto>page=new Page<>(current,pageSize);
        page.setSize(pageSize);
        page.setCurrent(current);
        page.setOptimizeCountSql(false);

        MPJLambdaWrapper<Material>wrapper = new MPJLambdaWrapper<Material>()
                .selectAll(Material.class)
                .eq(!PublicTools.checkLoginRole(),Material::getLocation, locationAddress)
                .eq("status",1)
                .orderByDesc(Material::getUpdateTime);
        Page<MaterialDto> materialDtoPage = selectJoinListPage(page, MaterialDto.class, wrapper);
        List<MaterialDto> materialDtoList = materialDtoPage.getRecords();
        return SaResult.data(materialDtoList);
    }

    @Override
    public SaResult getAllService() {
        String locationAddress = locationService.getAllByLoginId();
//        List<Material> MaterialList = new MPJLambdaWrapper<Material>()
//                .selectAll(Material.class)
//                .eq(PublicTools.checkLoginRole(), Material::getLocation, locationAddress)
//                .orderByDesc(Material::getId).list();
        MPJLambdaWrapper<Material>wrapper=new MPJLambdaWrapper<Material>()
              .selectAll(Material.class)
              .eq(!PublicTools.checkLoginRole(),Material::getLocation, locationAddress)
              .orderByDesc(Material::getUpdateTime);
        List<Material> materialList = selectJoinList(Material.class, wrapper);
        return SaResult.data(BeanUtil.copyToList(materialList,MaterialDto.class));

    }

//    确认最终盘点数据
    @Override
    public SaResult modifyFinalStockTakeNumberService() {
        List<Material> materialList = BeanUtil.copyToList((Collection<?>)getAllService().getData(), Material.class);
        List<Material> materialList_stockTakeAfter = new ArrayList<>();
        materialList.forEach(material -> {
            material.setNumber(material.getStockTakeNumber());
            material.setStockTakeNumber(0);
            materialList_stockTakeAfter.add(material);
        });
        updateBatchById(materialList_stockTakeAfter);

          return SaResult.ok("succeed");
    }

    @Override
    public SaResult getOneByIdService(Integer id) {
        if (id==null||id<=0){
            return SaResult.error("id数值错误");
        }
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }
        MPJLambdaWrapper<Material>wrapper=new MPJLambdaWrapper<Material>()
                .selectAll(Material.class)
                .eq(!PublicTools.checkLoginRole(),Material::getLocation, locationAddress)
                .selectCollection(MaterialPhoto.class,MaterialDto::getMaterialPhotoList)
                .eq(Material::getId,id)
                .leftJoin(MaterialPhoto.class,MaterialPhoto::getMaterialEncode,Material::getEncode);
        MaterialDto materialDto = selectJoinOne(MaterialDto.class, wrapper);

        List<MaterialPhoto> materialPhotoList = materialDto.getMaterialPhotoList();

        if (materialPhotoList.size()==1&&materialPhotoList.get(0).getMaterialEncode()==null){
            materialPhotoList.remove(0);
            return SaResult.data(materialDto);
        }
        else if (!BeanUtil.isEmpty(materialPhotoList)){
            for (MaterialPhoto materialPhoto : materialPhotoList) {
                String originalUrl = materialPhoto.getPhotoUrl();
                String newUrl = ServerBASEURL.BASEURL + originalUrl;
                materialPhoto.setPhotoUrl(newUrl);
            }
            return SaResult.data(materialDto);
        }
       else {
            return SaResult.data(materialDto);
        }

    }

    @Override
    public SaResult getOneByEncodeService(String encode) {
        String encodeTrim = StrUtil.trim(encode);
        if (StrUtil.isEmpty(encodeTrim)){
            return SaResult.error("材料编码不能为空");
        }
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }
        MPJLambdaWrapper<Material>wrapper=new MPJLambdaWrapper<Material>()
                .selectAll(Material.class)
                .eq(!PublicTools.checkLoginRole(),Material::getLocation, locationAddress)
                .selectCollection(MaterialPhoto.class,MaterialDto::getMaterialPhotoList)
                .eq(Material::getEncode,encodeTrim)
                .leftJoin(MaterialPhoto.class,MaterialPhoto::getMaterialEncode,Material::getEncode);
        MaterialDto materialDto = selectJoinOne(MaterialDto.class, wrapper);
        return SaResult.data(materialDto);
    }

    @Override
    @Transactional
    public SaResult deleteOneByIdService(Integer id) {
        if (id==null||id<=0){
            return SaResult.error("id参数错误");
        }
//        联表删除
        DeleteJoinWrapper<Material>wrapper=JoinWrappers.delete(Material.class)
                .deleteAll()
                .leftJoin(MaterialPhoto.class,MaterialPhoto::getMaterialEncode,Material::getEncode)
                .eq(Material::getId,id);
        boolean remove = deleteJoin(wrapper);
        return remove?SaResult.ok():SaResult.error();
    }

    @Override
    public SaResult getByMaterialNameService(String materialName,Integer current,Integer pageSize) {
        if (current==null||current<=0){
            current = PAGE_CURRENT;
        }
        if (pageSize==null||pageSize<=0){
            pageSize = PAGE_SIZE;
        }
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }
        Page<MaterialDto>page=new Page<>(current,pageSize);
        MPJLambdaWrapper<Material>wrapper = new MPJLambdaWrapper<Material>()
                .selectAll(Material.class)
                .eq(!PublicTools.checkLoginRole(),Material::getLocation, locationAddress)

                .like("material_name", materialName)
//                .groupBy("create_time")
                .orderByDesc(Material::getUpdateTime)
//                .selectCollection(MaterialPhoto.class,MaterialDto::getMaterialPhotoList)
//                .leftJoin(MaterialPhoto.class,MaterialPhoto::getMaterialEncode,Material::getEncode)
                ;
        Page<MaterialDto> materialDtoPage = selectJoinListPage(page, MaterialDto.class, wrapper);
        List<MaterialDto> materialDtoList = materialDtoPage.getRecords();
        return SaResult.data(materialDtoList);
    }


    @Override
    public SaResult getAllMaterialsTermsByMaterialNameService(String materialName) {
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }

        MPJLambdaWrapper<Material>wrapper=new MPJLambdaWrapper<Material>()
                .select( "count(id)")
                .eq(!PublicTools.checkLoginRole(),Material::getLocation, locationAddress)
                .like("material_name",materialName);
        Long l = selectJoinOne(Long.class, wrapper);
        return SaResult.data(l);
    }

    @Override
    public SaResult getAllMaterialTerms() {
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }
        MPJLambdaWrapper<Material>wrapper=new MPJLambdaWrapper<Material>()
                .select( "count(id)")
                .eq(!PublicTools.checkLoginRole(),Material::getLocation, locationAddress);
        Long l = selectJoinOne(Long.class, wrapper);
        return SaResult.data(l);
    }


    @Override
    public SaResult getByTypeName(String typeName,Integer orderBy,Integer current,Integer pageSize) {
        if (StrUtil.isEmpty(typeName)) {
            return SaResult.error("类型名称不能为空");
        }
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }

        if (current==null||current<=0){
            current = PAGE_CURRENT;
        }
        if (pageSize==null||pageSize<=0){
            pageSize = PAGE_SIZE;
        }
        if (orderBy==null||orderBy<=0){
            return SaResult.error("orderBy值不能为空或者小于等于零！");
        }
        boolean desc=true;
        boolean asc=false;
        if (orderBy!=1){
            desc=false;
            asc=true;
        }
        Page<MaterialDto>page=new Page<>(current,pageSize);
        //        跟一对多一样
        MPJLambdaWrapper<Material>wrapper=new MPJLambdaWrapper<Material>()
                .selectAll(Material.class)
                .eq("type_name",typeName)
                .eq(!PublicTools.checkLoginRole(),Material::getLocation, locationAddress)
//                .groupBy("create_time")
                .orderByDesc(Material::getUpdateTime)
//                .selectCollection(MaterialPhoto.class, MaterialDto::getMaterialPhotoList)
//                .leftJoin(MaterialPhoto.class,MaterialPhoto::getMaterialEncode,Material::getEncode)
                ;
//      selectJoinListPage，是一对多分页查询的方法，（也有selectJoinOne，只能出一条数据，这里不适用）
//        三个参数，第一个也分页对象page，第二个是EquipmentDto.class，第三个是查询条件对象
        Page<MaterialDto> materialDtoPage = selectJoinListPage(page, MaterialDto.class, wrapper);
        List<MaterialDto> materialDtoList = materialDtoPage.getRecords();
        return SaResult.data(materialDtoList);

    }

    @Override
    public SaResult getCountsByTypeName(String typeName) {
        if (StrUtil.isEmpty(typeName)) {
            return SaResult.error("类型名称不能为空");
        }
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }
        MPJLambdaWrapper<Material>wrapper=new MPJLambdaWrapper<Material>()
                .select( "count(id)")
                .eq("type_name",typeName)
                .eq(!PublicTools.checkLoginRole(),Material::getLocation, locationAddress);
        Long l = selectJoinOne(Long.class, wrapper);

        return SaResult.data(l);
    }

    @Override
    public SaResult getByMultifunctionService(String name, Integer current, Integer pageSize) {

        if (current == null||current<=0) {
            current = PAGE_CURRENT;
        }
        if (pageSize == null||pageSize<=0) {
            pageSize = PAGE_SIZE;
        }
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }

        if (StrUtil.isBlank(name)){
            return getAllByPageService(current,pageSize);
        }

        Page<MaterialDto>page=new Page<>(current,pageSize);
        Set<MaterialDto>finalResultList=new HashSet<>();

//        根据材料名称查询
        MPJLambdaWrapper<Material>wrapperByMaterialName=new MPJLambdaWrapper<Material>()
                .selectAll(Material.class)
                .like("material_name",name)
                .eq(!PublicTools.checkLoginRole(),Material::getLocation,locationAddress)
//                .groupBy("create_time")
                .orderByDesc(Material::getCreateTime)
//                .selectCollection(MaterialPhoto.class,MaterialDto::getMaterialPhotoList)
//                .leftJoin(MaterialPhoto.class,MaterialPhoto::getMaterialEncode,Material::getEncode)
                ;
        Page<MaterialDto> materialDtoPageByMaterialName = selectJoinListPage(page, MaterialDto.class, wrapperByMaterialName);
        List<MaterialDto> materialDtoListByMaterialName = materialDtoPageByMaterialName.getRecords();
        if (!materialDtoListByMaterialName.isEmpty()){
            finalResultList.addAll(materialDtoListByMaterialName);
        }
//        根据材料类型查询
        MPJLambdaWrapper<Material>wrapperByMaterialTypeName=new MPJLambdaWrapper<Material>()
                .selectAll(Material.class)
                .like("type_name",name)
                .eq(!PublicTools.checkLoginRole(),Material::getLocation,locationAddress)
//                .groupBy("create_time")
                .orderByDesc(Material::getUpdateTime)
//                .selectCollection(MaterialPhoto.class,MaterialDto::getMaterialPhotoList)
//                .leftJoin(MaterialPhoto.class,MaterialPhoto::getMaterialEncode,Material::getEncode)
                ;
        Page<MaterialDto> materialDtoPageByMaterialTypeName = selectJoinListPage(page, MaterialDto.class, wrapperByMaterialTypeName);
        List<MaterialDto> materialDtoListByMaterialTypeName = materialDtoPageByMaterialTypeName.getRecords();
        if (!materialDtoListByMaterialTypeName.isEmpty()){
            finalResultList.addAll(materialDtoListByMaterialTypeName);
        }

        //        根据创建人查询
        MPJLambdaWrapper<Material>wrapperByCreateBy=new MPJLambdaWrapper<Material>()
                .selectAll(Material.class)
                .like("create_by",name)
                .eq(!PublicTools.checkLoginRole(),Material::getLocation,locationAddress)
//                .groupBy("create_time")
                .orderByDesc(Material::getUpdateTime)
//                .selectCollection(MaterialPhoto.class,MaterialDto::getMaterialPhotoList)
//                .leftJoin(MaterialPhoto.class,MaterialPhoto::getMaterialEncode,Material::getEncode)
                ;
        Page<MaterialDto> materialDtoPageByCreateBy = selectJoinListPage(page, MaterialDto.class, wrapperByCreateBy);
        List<MaterialDto> materialDtoListByCreateBy = materialDtoPageByCreateBy.getRecords();
        if (!materialDtoListByCreateBy.isEmpty()){
            finalResultList.addAll(materialDtoListByCreateBy);
        }

        //        根据最后修改人查询
        MPJLambdaWrapper<Material>wrapperByUpdateBy=new MPJLambdaWrapper<Material>()
                .selectAll(Material.class)
                .like("last_update_by",name)
                .eq(!PublicTools.checkLoginRole(),Material::getLocation,locationAddress)
//                .groupBy("create_time")
                .orderByDesc(Material::getUpdateTime)
//                .selectCollection(MaterialPhoto.class,MaterialDto::getMaterialPhotoList)
//                .leftJoin(MaterialPhoto.class,MaterialPhoto::getMaterialEncode,Material::getEncode)
                ;
        Page<MaterialDto> materialDtoPageByUpdateBy = selectJoinListPage(page, MaterialDto.class, wrapperByUpdateBy);
        List<MaterialDto> materialDtoListByUpdateBy = materialDtoPageByUpdateBy.getRecords();
        if (!materialDtoListByUpdateBy.isEmpty()){
            finalResultList.addAll(materialDtoListByUpdateBy);
        }

        //        根据品牌查询
        MPJLambdaWrapper<Material>wrapperByBrand=new MPJLambdaWrapper<Material>()
                .selectAll(Material.class)
                .like("brand",name)
                .eq(!PublicTools.checkLoginRole(),Material::getLocation,locationAddress)
//                .groupBy("create_time")
                .orderByDesc(Material::getUpdateTime)
//                .selectCollection(MaterialPhoto.class,MaterialDto::getMaterialPhotoList)
//                .leftJoin(MaterialPhoto.class,MaterialPhoto::getMaterialEncode,Material::getEncode)
                ;
        Page<MaterialDto> materialDtoPageByBrand = selectJoinListPage(page, MaterialDto.class, wrapperByBrand);
        List<MaterialDto> materialDtoListByBrand = materialDtoPageByBrand.getRecords();
        if (!materialDtoListByBrand.isEmpty()){
            finalResultList.addAll(materialDtoListByBrand);
        }

//         根据encode查询
        String encodeUpperCase=name.toUpperCase();
        MPJLambdaWrapper<Material>wrapperByEncode=new MPJLambdaWrapper<Material>()
                .selectAll(Material.class)
                .like("encode",encodeUpperCase)
                .eq(!PublicTools.checkLoginRole(),Material::getLocation,locationAddress)
//                .groupBy("create_time")
                .orderByDesc(Material::getUpdateTime);
        Page<MaterialDto> materialDtoPageByEncode = selectJoinListPage(page, MaterialDto.class, wrapperByEncode);
        List<MaterialDto> materialDtoListByEncode = materialDtoPageByEncode.getRecords();
        if (!materialDtoListByEncode.isEmpty()){
            finalResultList.addAll(materialDtoListByEncode);
        }
        List<MaterialDto>materialDTOs=new ArrayList<>(finalResultList);

//        根据layout查询
        MPJLambdaWrapper<Material>wrapperByLayout=new MPJLambdaWrapper<Material>()
                .selectAll(Material.class)
                .like("layout",name)
                .eq(!PublicTools.checkLoginRole(),Material::getLocation,locationAddress)
                .orderByDesc(Material::getUpdateTime);
        Page<MaterialDto> materialDtoPageByLayout = selectJoinListPage(page, MaterialDto.class, wrapperByLayout);
        List<MaterialDto> materialDtoListByLayout = materialDtoPageByLayout.getRecords();
        if (!materialDtoListByLayout.isEmpty()){
            materialDTOs.addAll(materialDtoListByLayout);
        }

        //        对List内部元素重新按照创建时间从晚到早重新排序
        materialDTOs.sort(new Comparator<MaterialDto>() {
            @Override
            public int compare(MaterialDto o1, MaterialDto o2) {
                Date createTime1 = o1.getCreateTime();
                Date createTime2 = o2.getCreateTime();
                return createTime2.compareTo(createTime1);
            }
        });

        return SaResult.data(materialDTOs);

    }

    @Override
    public SaResult getCountByMultifunctionNameService(String name) {
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }
        if (StrUtil.isBlank(StrUtil.trim(name))){
            return getAllMaterialTerms();
        }

        Set<Material>finalCountsResultList=new HashSet<>();

//        根据材料名称查询
        MPJLambdaWrapper<Material>wrapperByMaterialName=new MPJLambdaWrapper<Material>()
                .selectAll(Material.class)
                .like("material_name",name)
                .eq(!PublicTools.checkLoginRole(),Material::getLocation,locationAddress);

        List<Material> materialListByMaterialName =list(wrapperByMaterialName);
        if (!materialListByMaterialName.isEmpty()){
            finalCountsResultList.addAll(materialListByMaterialName);
        }

//        根据材料类型查询
        MPJLambdaWrapper<Material>wrapperByMaterialTypeName=new MPJLambdaWrapper<Material>()
                .selectAll(Material.class)
                .like("type_name",name)
                .eq(!PublicTools.checkLoginRole(),Material::getLocation,locationAddress);
        List<Material> materialDtoListByMaterialTypeName = list(wrapperByMaterialTypeName);
        if (!materialDtoListByMaterialTypeName.isEmpty()){
            finalCountsResultList.addAll(materialDtoListByMaterialTypeName);
        }


        //        根据创建人查询
        MPJLambdaWrapper<Material>wrapperByCreateBy=new MPJLambdaWrapper<Material>()
                .selectAll(Material.class)
                .like("create_by",name)
                .eq(!PublicTools.checkLoginRole(),Material::getLocation,locationAddress);
        List<Material> materialDtoListByCreateBy =list(wrapperByCreateBy);
        if (!materialDtoListByCreateBy.isEmpty()){
            finalCountsResultList.addAll(materialDtoListByCreateBy);
        }

        //        根据最后修改人查询
        MPJLambdaWrapper<Material>wrapperByUpdateBy=new MPJLambdaWrapper<Material>()
                .selectAll(Material.class)
                .like("last_update_by",name)
                .eq(!PublicTools.checkLoginRole(),Material::getLocation,locationAddress);
        List<Material> materialDtoListByUpdateBy = list(wrapperByUpdateBy);
        if (!materialDtoListByUpdateBy.isEmpty()){
            finalCountsResultList.addAll(materialDtoListByUpdateBy);
        }

        //        根据品牌查询
        MPJLambdaWrapper<Material>wrapperByBrand=new MPJLambdaWrapper<Material>()
                .selectAll(Material.class)
                .like("brand",name)
                .eq(!PublicTools.checkLoginRole(),Material::getLocation,locationAddress);
        List<Material> materialDtoListByBrand = list(wrapperByBrand);
        if (!materialDtoListByBrand.isEmpty()){
            finalCountsResultList.addAll(materialDtoListByBrand);
        }

//         根据encode查询
        String encodeUpperCase=name.toUpperCase();
        MPJLambdaWrapper<Material>wrapperByEncode=new MPJLambdaWrapper<Material>()
                .selectAll(Material.class)
                .like("encode",encodeUpperCase)
                .eq(!PublicTools.checkLoginRole(),Material::getLocation,locationAddress);
        List<Material> materialDtoListByEncode = list(wrapperByEncode);
        if (!materialDtoListByEncode.isEmpty()){
            finalCountsResultList.addAll(materialDtoListByEncode);
        }

//        根据layout查询
        MPJLambdaWrapper<Material>wrapperByLayout=new MPJLambdaWrapper<Material>()
                .selectAll(Material.class)
                .like("layout",name)
                .eq(!PublicTools.checkLoginRole(),Material::getLocation,locationAddress);
        List<Material> materialDtoListByLayout = list(wrapperByLayout);
        if (!materialDtoListByLayout.isEmpty()){
            finalCountsResultList.addAll(materialDtoListByLayout);
        }
        return SaResult.data(finalCountsResultList.size());
    }

    @Override
    public void downloadFilesService(String[] files, HttpServletResponse response) throws IOException {
        FilesDownLoad.filesToZip(response,files,fileLocation);
    }

    @Override
    public SaResult modifyMaterialStatusService(Material material) {
        boolean b=updateById(material);
        return b?SaResult.ok():SaResult.error();
    }

    @Override
    public SaResult modifyStockTakeNumberService(Material material) {
        Material material_new=new Material();
        material_new.setId(material.getId());
        material_new.setStockTakeNumber(material.getStockTakeNumber());
        boolean b=updateById(material_new);
        return b?SaResult.ok():SaResult.error();
    }



    public boolean fileOperation(String encode, MultipartFile[] materialFile, HttpServletRequest request) {
//        创建一个equipmentPhotoDto集合作为向数据库写数据的容器
        List<MaterialPhotoDto> materialPhotoDtoList = new ArrayList<>();
//        创建日期目录
        String format = sdf.format(new Date());
//        详细目录名是date,存储equipphoto的目录，日期目录，encode目录
        String realPath = fileLocation + materialPhotoPath + format + encode;
//        创建文件对象
        File folder = new File(realPath);
//        定义全网络路径
        String url;
//        创建目录

        if (!folder.exists()) {
            folder.mkdirs();
        }
//        把前端传进来的文件列表遍历，并写进硬盘中，同时写入数据库中
        for (MultipartFile multipartFile : materialFile) {
            MaterialPhotoDto materialPhotoDto = new MaterialPhotoDto();
//            获取文件的原始文件名，并取得文件后缀名，如.jpg
            String originalFilename = multipartFile.getOriginalFilename();
            int i = 0;
            if (originalFilename != null) {
                i = originalFilename.lastIndexOf(".");
            }
            String substring;
            String newFileName = null;
            if (originalFilename != null) {
//             把截取文件名的后缀  “.jpg”
                substring = originalFilename.substring(i).toLowerCase();
//            重新拼接文件名加.jpg，前缀是登录名，如登录名为eric，整照片的全名就是eric.jpg
//            为避免文件名出行由于菜单名称相同，而相同造成覆盖，采用了一个7位的随机字符串拼接
                newFileName = RandomUtil.randomString(4).toUpperCase() +substring;
//            }
                try {
//                    通过transferTo方法，把文件写入磁盘
                    multipartFile.transferTo(new File(folder, newFileName));



//                    拼接全网络文件路径
                    url = materialPhotoPath+ format +encode+"/"+ newFileName;

//                    把url,encode,equipmentPhotoDto写入equipmentPhotoDto对象相应字段中
                    materialPhotoDto.setPhotoUrl(url);
                    materialPhotoDto.setMaterialEncode(encode);
                    materialPhotoDtoList.add(materialPhotoDto);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
//        把equipmentPhotoDto列表转换为equipmentPhoto列表
        List<MaterialPhoto> materialPhotoList = BeanUtil.copyToList(materialPhotoDtoList, MaterialPhoto.class);
//        写入数据库
        return materialPhotoService.saveBatch(materialPhotoList);
    }
    MaterialDto checkMaterial(MaterialDto materialDto) {
        String eqName = StrUtil.trim(materialDto.getMaterialName());
        if (StrUtil.isBlank(eqName)){
            materialDto.setMaterialName(null);
        }else {
            materialDto.setMaterialName(eqName);
        }

        String brand = StrUtil.trim(materialDto.getBrand());
        if (StrUtil.isBlank(brand)){
            materialDto.setBrand(null);
        }
        else {
            materialDto.setBrand(brand);
        }

        String model = StrUtil.trim(materialDto.getModel());
        if (StrUtil.isBlank(model)){
            materialDto.setModel(null);
        }
        else {
            materialDto.setModel(model);
        }

        String description = StrUtil.trim(materialDto.getDescription());
        if (StrUtil.isBlank(description)){
            materialDto.setDescription(null);
        }

        String location = StrUtil.trim(materialDto.getLocation());
        if (StrUtil.isBlank(location)){
            materialDto.setLocation(null);
        }
        else {
            materialDto.setLocation(location);
        }

        String pieces = StrUtil.trim(materialDto.getPieces());
        if (StrUtil.isBlank(pieces)){
            materialDto.setPieces(null);
        }
        else {
            materialDto.setPieces(pieces);
        }
        return materialDto;
    }
}
